#!/usr/bin/python2.4
#
# Copyright 2009 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Base handler class that all other handlers inherit from."""

# AppEngine
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

# Cruise Control
import dstore

# Python
import os
import logging

# Software Version

CC_VERSION = os.environ.get('CURRENT_VERSION_ID', 'N/A').replace('-', '.')

class BaseHandler(webapp.RequestHandler):
  """Base class from which all other handler classes inherit."""

  def __init__(self):
    """Constructor. Sets basic data used by each request."""
    self.log = logging

    # Get user module info
    self.gia_user = users.GetCurrentUser()
    self.is_admin = users.IsCurrentUserAdmin()

    # Initialize datastore
    self.db = dstore.DataStore(self.gia_user, self.is_admin)

    # Cruise Control for AppEngine User info
    self.user = self.db.GetCurrentUser()

    # Site Info
    self.blog = self.db.GetBlog()
    self.blog_template = self.blog.template
    self.blog_links = self.db.GetLinks()
    self.published_pages = self.db.GetPublishedPages()

    # Initialize vars
    self.user_warnings = {}
    self.user_message = {}
    self.http_status_code = 200

  def Init(self, request_method):
    """Initializes some more instance variables used by other handlers.

    These variables are not set in __init__ above because when this class is
    initialized, the request object has not been set yet by
    webapp.RequestHandler

    Args:
      request_method: string for GET or POST
    """
    # Request method
    self.request_method = request_method

    # Requested path info
    self.path = self.request.path_info
    self.path_list = self.GetPathList()
    self.requested_page = self.GetSelectedPage()
    self.is_admin_page = self.path_list[0] == 'admin'

    # Request params
    self.params = self.request.params

    # Default HTML template vars
    self.html_vars = {'user': self.user,
                      'is_admin': self.is_admin,
                      'blog': self.blog,
                      'page_title': self.blog.name + ' - ' + self.blog.tagline,
                      'blog_links': self.blog_links,
                      'is_admin_page': self.is_admin_page,
                      'path_list': self.path_list,
                      'path': self.path,
                      'requested_page': self.requested_page,
                      'published_pages': self.published_pages,
                      'login_url': users.CreateLoginURL(self.request.uri),
                      'logout_url': users.CreateLogoutURL(self.request.uri),
                      'blog_template': self.blog_template,
                      'this_url': self.request.url,
                      'cc_version': CC_VERSION}

    self.Call()

  def get(self):
    """Called on GET requests."""
    self.Init('GET')

  def post(self):
    """Called on POST requests."""
    self.Init('POST')

  def Call(self):
    """Main method for all handlers that inherit this class."""
    pass

  def SetMetaInfo(self, entity):
    """Given an entity (blog, page, post), sets the associated meta info.

    Args:
        entity: datastore entity object.
    """
    if entity:
      self.html_vars['canonical'] = entity.canonical
      self.html_vars['keywords'] = entity.keywords
      self.html_vars['description'] = entity.description
      self.html_vars['noindex'] = entity.noindex
      self.html_vars['noarchive'] = entity.noarchive
      self.html_vars['nofollow'] = entity.nofollow
      self.html_vars['nosnippet'] = entity.nosnippet
      self.html_vars['noodp'] = entity.noodp

  def GetPathList(self):
    """Splits the requested path into a list, removing any empty elements.

    For example, the path /2009/02/02/my-post-title, returns
    [2009,02,02,my-post-title]

    Returns:
      list
    """
    path_list = self.path[1:].split('/')
    filtered_path = []
    for directory in path_list:
      if directory.replace(' ', ''):
        filtered_path.append(directory)
    if not filtered_path:
      return ['']
    return filtered_path

  def GetSelectedPage(self):
    """Attempts to extract the requested page."""
    page = ''
    if len(self.path_list) == 1:
      if self.path_list[0] in ['', 'index', 'index.html']:
        return ''
      return self.path_list[0]

    # Assumes either a specific page (i.e., /specific-page) was requested or a
    # deep page to a blog post (i.e., /2009/02/02/post-title)
    page = ''
    if self.path_list[0]:
      try:
        int(self.path_list[0])
      except ValueError:
        page = self.path_list[-1]
    return page

  def GoToPage(self, loc, permanent=False):
    """Wrapper for self.redirect."""
    self.redirect(loc, permanent)

  def RenderPage(self, page):
    """Returns the desired page to the user.

    Also, checks to see if an admin has requested to view the reqested page
    using an alternate template.

    Args:
      page: string HTML template file name that is to be displayed for the user.
    """
    """ We set this here because os.environ['HTTP_HOST'] isn't available earlier."""
    if os.environ.get('HTTP_HOST'): 
      self.html_vars['http_host'] = os.environ['HTTP_HOST'] 
    else: 
      self.html_vars['http_host'] = os.environ['SERVER_NAME']

    if self.is_admin:
      preview = self.params.get('preview_template')
      if preview:
        self.blog_template = preview
    site_template = 'templates/' + self.blog_template + '/' + page
    self.html_vars['template'] = self.blog_template
    if self.http_status_code != 200:
      self.error(self.http_status_code)
    path = os.path.join(os.path.dirname(__file__), site_template)
    self.response.out.write(template.render(path, self.html_vars))